#include "list.h"
#include "interrupt.h"

/*初始化双向链表*/
void list_init(struct list* list){
    list->head.prev = NULL;
    list->head.next = &list->tail;
    list->tail.prev = &list->head;
    list->tail.next = NULL;
};

/*把链表元素elem插入在元素before之前*/
void list_insert_before(struct list_elem* before, struct list_elem* elem){
    enum intr_status old_status = intr_disable();
/*将before元素的前驱元素的后继元素更新为elem，*/
    before->prev->next = elem;
/*更新elem自己的前驱结点为before的前驱
    elem的后继为before*/
    elem->prev = before->prev;
    elem->next = before;
/*before更新前驱结点elem*/
    before->prev = elem;
    intr_set_status(old_status);
}

/*添加元素到列表队首，*/
void list_push(struct list* plist, struct list_elem* elem){
    list_insert_before(plist->head.next, elem);
}
/*添加元素到列表队尾，*/
void list_append(struct list* plist, struct list_elem* elem){
    list_insert_before(&plist->tail, elem);
}
/*使元素脱离链表*/
void list_remove(struct list_elem* pelem){
    enum intr_status old_status = intr_disable();
    pelem->prev->next = pelem->next;
    pelem->next->prev = pelem->prev;
    intr_set_status(old_status);
}
/*将链表第一个元素弹出去并返回*/
struct list_elem* list_pop(struct list* plist){
    struct list_elem* elem = plist->head.next;
    list_remove(elem);
    return elem;
}
/*链表中查找元素obj_elem，成功返回true，*/
int elem_find(struct list* plist, struct list_elem* obj_elem){
    struct list_elem* elem = plist->head.next;
    while (elem != &plist->tail){
        if(elem == obj_elem){
            return 1;
        }
        elem = elem->next;
    }
    return 0;
}

/*遍历列表中所以元素，逐个判断是否有符合条件的元素*/
struct list_elem* list_traversal(struct list* plist, function func, int arg){
    struct list_elem* elem = plist->head.next;
/*如果队列为空，就必然没有符合条件的结点，*/
    if(list_empty(plist)){
        return NULL;
    }
    while(elem != &plist->tail){
        if(func(elem, arg)){
        /*符合条件停止遍历*/
            return elem;
        }
        elem = elem->next;
    }
    return NULL;
}

/*返回链表长度*/
uint32_t list_len(struct list* plist){
    struct list_elem* elem = plist->head.next;
    uint32_t length = 0;
    while(elem != &plist->tail){
        length++;
        elem = elem->next;
    }
    return length;
}

/*判断链表是否为空*/
int list_empty(struct list* plist){
    return (plist->head.next == &plist->tail ? 1 : 0);
}



